home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.09 Sep 96 / Lotus Notes / MakeBook.c < prev   
Encoding:
C/C++ Source or Header  |  1996-08-14  |  10.0 KB  |  270 lines  |  [TEXT/R*ch]

  1.  
  2. /* This is not the full source, nor should you expect it to compile. For more information, consult the Lotus Notes SDK - ed/wgi */
  3.  
  4. //Globals
  5. FILE        *outfile = NULL;
  6. long        uniqueLabelCounter = 0;
  7. char        *field_text;
  8.  
  9. //Main
  10.  
  11. /* This standalone program is declared with argc and argv, even though these arguments cannot be used in the MacOS, unless it were to be built as an MPW tool. Aside from the conditional code for initializing the MacOS toolbox, all of this source is 100% platform independent. (The actual sample code on the Notes C API Toolkit CD ROM contains a macro that hides platform specific initialization.)
  12.  
  13. All output from this program goes to a text file, which is created and written using the standard C file i/o routines. Again, this choice of file i/o was made for platform independence. In Notes API applications, one may choose to use conditionally compiled code to add platform specific file system functionality such as MacOS file types.
  14.  
  15. NotesInitExtended() is a Notes API function that initializes the Notes runtime library. At the end of main(), NotesTerm() is called. Every standalone program must have one set of init and term calls. Multi-threaded applications must have one set of calls for each thread. In this program, NotesTerm() is called as part of the macro API_RETURN().
  16.  
  17. The database is opened using NSFDbOpen(), processed with the function ReadDatabase(), and then closed using NSFDbClose(). The open function returns a “handle” to the database, which is then used by all functions that refer to that database. NSFDbOpen() takes the name of database as a full pathname, or as a filename if that database is stored locally. If the database is stored on a Notes server, there is an API function that will build the pathname.*/
  18.  
  19. void main(int argc, char *argv[])
  20. {
  21.     DBHANDLE    db_handle;                 // handle of source database
  22.     STATUS        error = NOERROR;    // return status from API calls
  23.  
  24. #ifdef MAC
  25.         InitMacToolBox();
  26. #endif
  27.  
  28.     if ((outfile = fopen("book.src", "w")) != NULL)
  29.     {    
  30.         //
  31.         // Output data that is required by the Apple Book Maker application, for the 
  32.         // creation of a Newton Book.
  33.         //
  34.         // For more information, please refer to the “Newton Book Maker User’s Guide”,
  35.         // which is included with the Apple’s Newton Toolkit for MacOS and Windows.
  36.         //
  37.         fprintf(outfile, 
  38. "\
  39. .isbn Notes:LOTUS\n\
  40. .date 02/05/96\n\
  41. .author Rick Gansler\n\
  42. .publisher Lotus Development Corp.\n\
  43. .copyright (c) 1996 Lotus Development Corp.\n\
  44. .shorttitle API User\n\
  45. .title Lotus Notes – API User's Guide\n\
  46. .blurb\n\
  47. The Lotus Notes API User's Guide exported from Notes to
  48. Newton Book format.\n\
  49. .layout Indented 1 Sidebar 11\n\
  50. .layout TitlePage 12 NoTitle\n\
  51. .layout ContentsPage 2 Sidebar 10 Main NoTitle\n\
  52. .layout Default 12\n\
  53. ");     
  54.  
  55.         // Initialize the Notes runtime library
  56.         if (NotesInitExtended(argc, argv))
  57.             NOTES_INIT_ERROR;
  58.         
  59.         // Open the database
  60.         if (error = NSFDbOpen("API40UG.NSF", &db_handle))
  61.             API_RETURN(ERR(error));
  62.         
  63.         field_text = (void *)malloc(32000);
  64.  
  65.         // Generate the Newton Book contents
  66.         uniqueLabelCounter = 0;
  67.         error = ReadDatabase(db_handle);
  68.         if (error)
  69.         {
  70.             NSFDbClose(db_handle));
  71.             API_RETURN(ERR(error));
  72.         }
  73.  
  74.         // Close the database
  75.         if (error = NSFDbClose(db_handle))
  76.             API_RETURN(ERR(error));
  77.             
  78.         fclose(outfile);
  79.         free(field_text);
  80.     }
  81.  
  82.     API_RETURN(NOERROR);
  83. }
  84.  
  85. /*
  86. ReadDatabase
  87.  
  88. ReadDatabase() takes a database handle, and reads each document in the database. In this case, the database has a view that is defined in the database. One could also create a custom view at runtime. The pairing of a view and a collection is analogous to a search result that has been sorted. Once the collection has been opened, ReadEntries() is called to return a buffer containing a reference to each document in the collection, plus a counter that indicates how many documents are in the collection. Each document is identified by its unique note id. A loop is used to iterate through the buffer and pull out each note id, which is passed to the function ReadNote().*/
  89.  
  90. STATUS    ReadDatabase(DBHANDLE db_handle)
  91. {
  92.     STATUS                error=NOERROR;    // return status from API calls
  93.     NOTEID                ViewID;                // note id of the view
  94.     HCOLLECTION    hCollection;        // collection handle
  95.     COLLECTIONPOSITION CollPosition;     // index into collection
  96.     HANDLE                hBuffer;                // handle to buffer of info
  97.     DWORD                EntriesFound;    // number of entries found
  98.     WORD                    SignalFlag;        // signal and share warning flags
  99.     BYTE                    *pBuffer;            // pointer into info buffer
  100.     DWORD                I;                            // a counter
  101.     NOTEID                EntryID;                // a collection entry id
  102.  
  103.     // Get the note id of the view we want
  104.     if (error = 
  105.                 NIFFindView(db_handle,"TABLE OF CONTENTS",&ViewID))
  106.         return(error);
  107.  
  108.     // Get the current collection using this view
  109.     if (error = NIFOpenCollection(
  110.                  db_handle,        // handle of db with view
  111.                  db_handle,        // handle of db with data
  112.                  ViewID,                // note id of the view
  113.                  0,                        // collection open flags
  114.                  NULLHANDLE,        // handle to unread ID list (input & return)
  115.                  &hCollection,    // collection handle (return)
  116.                  NULLHANDLE,        // handle to open view note (return)
  117.                  NULL,                    // universal note id of view (return)
  118.                  NULLHANDLE,        // handle to collapsed list (return)
  119.                  NULLHANDLE))    // handle to selected list (return)
  120.             return(error);
  121.  
  122.         // Set a COLLECTIONPOSITION to the beginning of the collection
  123.         CollPosition.Level = 0;
  124.         CollPosition.Tumbler[0] = 0;
  125.  
  126.         // Get the note ID and summary of every entry in the collection. In the 
  127.         // returned buffer, first comes all of the info about the first entry, then 
  128.         // all of the info about the 2nd entry, etc. For each entry, the info is
  129.         // arranged in the order of the bits in the READ_MASKs.
  130.         do
  131.         {
  132.             if (error = NIFReadEntries(
  133.                     hCollection,                // handle to this collection
  134.                     &CollPosition,            // where to start in collection
  135.                     NAVIGATE_NEXT,            // order to use when skipping
  136.                     1L,                                // number to skip
  137.                     NAVIGATE_NEXT,            // order to use when reading
  138.                     0xFFFFFFFF,                // max number to read
  139.                     READ_MASK_NOTEID,    // info we want
  140.                     &hBuffer,                    // handle to info buffer (return)
  141.                     NULL,                            // length of info buffer (return)
  142.                     NULL,                            // entries skipped (return)
  143.                     &EntriesFound,        // entries read (return)
  144.                     &SignalFlag))        // share warning & more signal flag return
  145.             {
  146.                     NIFCloseCollection(hCollection);
  147.                     return(error);
  148.             }
  149.  
  150.                 // Check to make sure there was a buffer of information returned
  151.                 if (hBuffer == NULLHANDLE)
  152.                 {
  153.                     NIFCloseCollection(hCollection);
  154.                     NSFDbClose(db_handle);
  155.                     return(NOERROR);
  156.                 }
  157.  
  158.                 //
  159.                 // Lock down (freeze the location) of the information buffer. Cast
  160.                 // the resulting pointer to the type we need.
  161.                 //
  162.                 // OSLockObject() is sort of like the Notes equivalent of locking a
  163.                 // Mac handle and then dereferencing it. However, Notes abstracts memory 
  164.                 // management, since each Notes platform may implement it 
  165.                 // differently. For example, a Windows handle is a very different kind
  166.                 // of data object than a Mac handle.
  167.                 //
  168.                 pBuffer = (BYTE *) OSLockObject (hBuffer);
  169.  
  170.                 // Start a loop that extracts the info about each collection entry from
  171.                 // the information buffer
  172.                 for (i = 1; i <= EntriesFound; i++)
  173.                 {
  174.                     // Get the NoteID of this entry
  175.                     EntryID = *(NOTEID*)pBuffer;
  176.  
  177.                     // Advance the pointer over the NoteID
  178.                     pBuffer += sizeof(NOTEID);
  179.  
  180.                      if (! (NOTEID_CATEGORY & EntryID))
  181.                          ReadNote(EntryID, db_handle);
  182.                 }
  183.                 
  184.                 // Unlock the list of NoteIDs. 
  185.                 OSUnlockObject(hBuffer);
  186.  
  187.                 // Free the memory allocated by NIFReadEntries
  188.                 OSMemFree(hBuffer);
  189.         }    while (SignalFlag & SIGNAL_MORE_TO_DO);
  190.  
  191.     // Close the collection
  192.     error = NIFCloseCollection(hCollection);
  193.     
  194.     return(error);
  195. }
  196.  
  197.  
  198. /*ReadNote
  199.  
  200. ReadNote() takes a note id and a database handle, opens the document referred to by the note id, reads only the fields in that document that are needed, formats them, and outputs them to a text file in a form that can be imported by the Apple program Book Maker.*/
  201.  
  202. STATUS far PASCAL ReadNote(NOTEID noteID, DBHANDLE db_handle)
  203. {
  204.     NOTEHANDLE        note_hdl;
  205.     WORD                    field_len;
  206.     long                    sectionNum_num;
  207.     long                    chapterNum_num;
  208.     char                    sectionName_text[100];
  209.     char                    titleName_text[100];
  210.     STATUS                error;
  211.     static    long    prevSectionNumber = –1;    // this is a static
  212.        
  213.     // Open the document whose note id was passed to this function
  214.     if (error = NSFNoteOpen(db_handle,    noteID, 0, ¬e_hdl))
  215.         return(ERR(error));
  216.         
  217.     sectionNum_num = NSFItemGetLong(note_hdl, "SectionNumber", 0L);
  218.  
  219.     chapterNum_num = NSFItemGetLong(note_hdl, "Chapter", 0L);
  220.  
  221.     field_len = NSFItemGetText(note_hdl, "SectionName",
  222.                                                         sectionName_text, 
  223.                                                         sizeof (sectionName_text));
  224.  
  225.     field_len = 
  226.             NSFItemGetText(note_hdl, "title", titleName_text,
  227.             sizeof(titleName_text));
  228.  
  229.     // If this document is the first in a new chapter, create a new heading in the Newton
  230.     // Book Overview (or table of contents)
  231.     if (sectionNum_num > prevSectionNumber)
  232.     {
  233.         prevSectionNumber = sectionNum_num;
  234.         fprintf(outfile, 
  235.                 ".subject 1 startspage centered name=%ld\n",
  236.                 (long)uniqueLabelCounter++);
  237.         fprintf(outfile,
  238.                 "(%ld) %s\n",sectionNum_num,sectionName_text);
  239.     }
  240.     
  241.     // Every document gets an entry in the Newton Book Overview. 
  242.     fprintf(outfile,
  243.             ".subject 2 name=%ld\n", uniqueLabelCounter++);
  244.     fprintf(outfile,
  245.             "(%ld) %s\n", chapterNum_num, titleName_text);
  246.     
  247.     // Body of the document (Notes Rich Text field)
  248.     if (NSFItemConvertToText(note_hdl, "text", field_text,
  249.                                                     FILE_SIZE, '\0') > 0)
  250.     {
  251.         // If the data from Notes contains a \r\n, then remove the \r. 
  252.         // The code for this function is not included in this listing.
  253.         ProcessLineFeeds(field_text);
  254.  
  255.         // If the data from Notes had a line that began with a period, that would 
  256.         // confuse Book Maker, so we replace the period with a space. 
  257.         // All Book Maker commands begin with a period at the start of a line.
  258.         // The code for this function is not included in this listing.
  259.         CorrectLinesStartingWithPeriod(field_text);
  260.  
  261.         fprintf(outfile, "%s\n", field_text);
  262.     }
  263.         
  264.     // Close the note
  265.     if (error = NSFNoteClose(note_hdl))
  266.         return(ERR(error));
  267.  
  268.     return (NOERROR);
  269. }
  270.